﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Threading;
using System.IO;
using PromoServer.Library.BLL;
using PromoServer.Library.Data;
using PromoServer.Library.Entities;
using PromoServer_WPF.Views;
using PromoServer.Library;

namespace PromoServer_WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private PSLayout psLayout;
        private PSDevice psDevice;
        private List<Device> lstDevices;
        private bool refreshDevicesSwitch = false;
        private PromoSocketServer promoServer;
        private BackgroundWorker addNewDevicesBackgroundWorker;
        
        public MainWindow()
        {
            InitializeComponent();

            // First, run cleanup routine
            CleanupTempImageFiles();

            // Init PS objects
            promoServer = new PromoSocketServer();
            psLayout = new PSLayout();
            psDevice = new PSDevice();
            lstDevices = new List<Device>();

            // Subscribe to PromoServer events
            promoServer.DeviceRegistered += new RegisteredNewDeviceEventHandler(NewDeviceRegistered);
            promoServer.NewDeviceFound += new FoundNewDeviceEventHandler(NewDeviceFound);
            promoServer.DeviceResolutionChanged += new DeviceResolutionChangedEventHandler(DeviceResolutionChanged);

            // Initialize background workers
            addNewDevicesBackgroundWorker = new BackgroundWorker();
            addNewDevicesBackgroundWorker.WorkerReportsProgress = true;
            addNewDevicesBackgroundWorker.DoWork += new DoWorkEventHandler(newDevice_DoWork);
            addNewDevicesBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(newDevice_ProgressChanged);
            addNewDevicesBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(newDevice_RunWorkerCompleted);

            // Load registered devices
            RefreshDevices();

            // Start new device process
            addNewDevicesBackgroundWorker.RunWorkerAsync();
        }

        private void RefreshDevices()
        {
            try
            {
                // Load registered devices
                stackDevices.Children.Clear();
                lstDevices = psDevice.GetDeviceList();
                foreach (Device device in lstDevices)
                {
                    stackDevices.Children.Add(new DeviceView(device));
                }
            }
            catch (Exception ex)
            {
                // Log error
                PromoLog promoLog = new PromoLog();
                promoLog.Log("MainWindow.RefreshDevices", ex.Message, true);

                // Display error message to user
                MessageBox.Show("Failed to load devices. Error: " + ex.Message);
            }
        }

        private void DeviceResolutionChanged(string deviceHostName)
        {
            try
            {
                string displayName = psDevice.GetDisplayName(deviceHostName);
                MessageBox.Show(string.Format("WARNING: The device resolution for {0} has changed and may not display correctly until a new layout is sent", displayName));
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }
        }

        private void NewDeviceRegistered(Device newDevice)
        {
            try
            {
                // Set refresh devices switch
                refreshDevicesSwitch = true;
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }

        }

        private void NewDeviceFound(string hostName)
        {
            MessageBox.Show("Found new device: " + hostName);
        }

        private void CleanupTempImageFiles()
        {
            // Delete orphaned temporary image files
            string imageFileName = string.Empty;
            foreach (string imageFilePath in System.IO.Directory.GetFiles(Properties.Settings.Default.Images_Directory))
            {
                // Get file name from full file path
                FileInfo fi = new FileInfo(imageFilePath);
                imageFileName = fi.Name;

                // If file is temp, delete
                if (imageFileName.Substring(0, 4) == "tmp_")
                    File.Delete(imageFilePath);
            }
        }

        #region BACKGROUND_WORKER_NEW_DEVICE

        private void newDevice_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (refreshDevicesSwitch)
                {
                    refreshDevicesSwitch = false;
                    addNewDevicesBackgroundWorker.ReportProgress(100);
                }
                else
                    Thread.Sleep(100);
            }
        }

        private void newDevice_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Refresh device views
            RefreshDevices();
        }

        private void newDevice_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // BG worker runs constantly
        }

        #endregion

        private void menuNewLayout_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                DesignLayoutWindow designLayoutWindow = new DesignLayoutWindow(true);
                designLayoutWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }
        }

        private void menuEditLayouts_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                DesignLayoutWindow designLayoutWindow = new DesignLayoutWindow(false);
                designLayoutWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }
        }

        private void menuNewSchedules_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ScheduleEditorWindow scheduleEditWindow = new ScheduleEditorWindow(true);
                scheduleEditWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }
        }

        private void menuEditSchedules_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ScheduleEditorWindow scheduleEditWindow = new ScheduleEditorWindow(false);
                scheduleEditWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                // Display error message to user
                MessageBox.Show(ex.Message);
            }
        }
    }
}
